package com.googlecode.afdbaccess.config.propertyconfig;

import org.apache.log4j.Logger;

import com.googlecode.afdbaccess.cache.connectionpool.interfaces.ConnectionPoolFactory;
import com.googlecode.afdbaccess.cache.exceptions.DataLayerException;


public class ReadConfiguration {
  private final static Logger log = Logger.getLogger(ReadConfiguration.class);  
    
  public static ConnectionPoolFactory instanciatePoolFactory() throws DataLayerException {
    return ReadConfiguration.instanciatePoolFactory(null, DBCPPoolFactoryForMySql.class);
  }

  public static ConnectionPoolFactory instanciatePoolFactory(Class<? extends ConnectionPoolFactory> defaultPoolClassClass) throws DataLayerException {
    return ReadConfiguration.instanciatePoolFactory(null, defaultPoolClassClass);
  }

  public static ConnectionPoolFactory instanciatePoolFactory(String root) throws DataLayerException {
    return ReadConfiguration.instanciatePoolFactory(root, null);
  }

  public static ConnectionPoolFactory instanciatePoolFactory(String root, Class<? extends ConnectionPoolFactory> defaultPoolClassClass) throws DataLayerException {
    String rootString = "";
    if(root != null && root.trim().equals("") == false) {
      rootString = root + ".";
    }

    String poolClass = System.getProperty(rootString + "pool-class");

    ConnectionPoolFactory poolFactory = null;
    if(poolClass != null && poolClass.trim().equals("") == false) {
      try {
        // use custom pool
        log.debug("Found information about custom dbPool factory. Trying to instanciate: " + poolClass);

        Class<?> poolClassClass = Class.forName(poolClass);
        try {
          poolFactory = (ConnectionPoolFactory)poolClassClass.newInstance();
        } catch (IllegalAccessException exception) {
          log.warn("Exception was thrown when instanciating custom dbPool factory!", exception);
        } catch (InstantiationException exception) {
          log.warn("Exception was thrown when instanciating custom dbPool factory!", exception);
        }
      } catch (ClassNotFoundException exception) {
        log.warn("Exception was thrown when trying to find class for custom dbPool factory!", exception);
      }
    }

    if (poolFactory == null && defaultPoolClassClass != null) {
      log.debug("Couldn't find/create a configured dbPool factory. Trying default dbPool factory instead.");
      try {
        poolFactory = defaultPoolClassClass.newInstance();
      } catch (IllegalAccessException exception) {
        log.warn("Exception was thrown when instanciating custom default dbPool factory!", exception);
      } catch (InstantiationException exception) {
        log.warn("Exception was thrown when instanciating custom default dbPool factory!", exception);
      }
    }

    if (poolFactory == null) {
      throw new DataLayerException("Couldn't instanciate a custom dbPool factory. See logged warnings for possible reasons. poolClass String: " + poolClass);
    }

    return poolFactory;
  }

  static int getIntSystemProperty(String propertyName, int defaultValue) {
    String intStringValue = System.getProperty(propertyName);
    try {
      return Integer.parseInt(intStringValue);
    }
    catch (NumberFormatException e) {
      return defaultValue;
    }
  }
}